решил проблему костылём - дал возможность рабочему строить только башню - шаблонку, которая в свою очередь может улучшаться в две указанные башни. Взаимосвязь поставить только от башни - шаблонки. Лимит поставил на башню шаблонки.
Но тема не закрыта. Хотелось бы узнать можно ли решить проблему без костылей.
Это баг варика. Когда ты используешь несколько диалогов и показываешь их подряд, название Title надо каждый раз заново создавать. Если бы у тебя был один диалог и ты бы его показывал несколько раз подряд - заголовок сохраниться.
Могу посоветовать при пересоздании запускать триггер dialog повторно.
можно писать до тех пор пока не закончится лимит потока (примерно 5000 раз)
но я бы юзал массивы и циклы
нафиг писать 1000 строк кода когда можно написать 5
si__UnitPolar_I и не надо уменьшать
она увеличивается только в том случае если нету свободных ячеек
каждый раз когда ты вызываешь destroy() появляется свободная ячейка
советую почитать мануал чтобы понять как это работает
Что-то мне кажется, что 162 - это предел для структур, которые содержат в себе массив, поэтому нужно указывать размер, если ставить внутри структуры массив переменных и при этом данный предел - 162. Компилятор разбивает стандартный массив в размере 8192 на более меньшие части. Например, структура - группа юнитов содержит массив юнитов 20, то для каждой структуры будет выделяться строго 20 ячеек общего массива юнитов в размере 8192.
Это неважно 2 или 8895465, все что вам нужно это отловить урон в 0.0 ед. от лица того кто кастует стрелы или врубил автокаст и атакует, а так же проверить на бафф стрел, если бафф стрел есть и юнит получил 0.00 ед. урона то в него прилетала стрела от автокаста...
Я сейчас по тихому делаю систему боя и героев под нее. У каждого героя 7 способностей и при прокачке скила открываются еще скилы, которые увеличат мощь данного скила, добавят баф/дебаф, изменит манакост, перезарядку и особая прокачка которая сильно улучшает 1 сторону способности за счет снижения другой
К примеру: способность получает +100% к силе аттаки но нее действует параметр уклонения.
Критический шанс удара спелом повышен, но сила крита снижена и т.д
Ааа, ну тогда смотри
не_кликабельность Сларка делается так
а - его морфят в юнит без модельки
б - ему дают москитов и отбирают (что бы на него нельзя было кликнуть, но можно было выделить)
в - все события "атакован" приводятся к действию "стоп", если это Сларк
г - аура регена игнорирует то что Сларка видят
у тебя на пути стоит пункт Б, т.к. что бы умные люди не заменяли себе пустую модельку (пункт А) на нормальную и не могли на неё в итоге тыкать... Так что в итоге - ты можешь её заменить, но тыкнуть всё равно не сможешь... шах и мат
идея неплохая, если не считать, что заклинание будет диспеллить эффект похожего заклинания.
Например если юнит в стане от молота бурь, то молот бурь-даммикаст снимет бафф с него. С кислотной бомбой и т.п. однозначно диспеллит, насчёт молота - скорее всего.
Нет, станы перебивают тока сильный, слабого. Ну или есть большое отличие в уровнях. Аксид бомбы будут перебивать если урон выше, а так просто продливать бафф, чертики тоже самое.
Кстати да, забыл написать, длительность 0.01, бафф сразу же после проверки удаляем.
Если вы юзайте аксид бомбу для нанесения урона, придется наносит урон триггерно.
Кстати, большинство скиллов вроде аксид бомбы или чертика работают так.
Сначала 0.00 ед. урона, после бафф, после урон указанный в поле способности.
Но молот бурь работает иначе, сначала урон указанный в поле способности, после 0.00 ед. урона и бафф стана.
Объясню, почему я удалил код: после проведённого за кодом времени, я понял, что сильно погорячился, задав такой глупый вопрос. Стоило отдохнуть, проветрить голову, и решение нашлось. Тем, кто столкнулся с хоть самую малость, но похожей проблемой, дам совет: всегда проверяйте соответствия заклинаний, написанных в коде jass (CTRL + D, если кто не знает, как узнать id заклинания) и ,конечно, сам синтаксис. Также посоветую не утраивать "свалку" в коде, как это сделал я. В общем, если кому интересно, как я решил проблему, пишите - расскажу или даже помогу если у вас она схожая.(Всё дело во внимательности)...
Сброшу код триггера таким, каким я его хотел видеть изначально:
function MU_Check_lvl_four takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 4 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_three takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 3 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_two takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 2 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_one takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 1 ) ) then
return false
endif
return true
endfunction
function MU_Second_Conditions takes nothing returns boolean
if ( not ( UnitHasBuffBJ(GetEventDamageSource(), 'B008') == true ) ) then
return false
endif
if ( not ( GetEventDamageSource() == udg_Akame_Killer ) ) then
return false
endif
return true
endfunction
function MU_Start_Conditions takes nothing returns boolean
if ( not ( UnitHasBuffBJ(GetAttacker(), 'B008') == true ) ) then
return false
endif
if ( not ( GetAttacker() == udg_Akame_Killer ) ) then
return false
endif
return true
endfunction
function Trig_MU_Conditions takes nothing returns boolean
if ( not MU_Start_Conditions() ) then
return false
endif
return true
endfunction
function MU_Venum_Check takes nothing returns boolean
if ( not ( udg_MU_Venum_counter == 2 ) ) then
return false
endif
return true
endfunction
function MU_del takes nothing returns nothing
if ( MU_Check_lvl_one() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00X', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00X', GetEventDamageSource() )
else
if ( MU_Check_lvl_two() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00U', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00U', GetEventDamageSource() )
else
if ( MU_Check_lvl_three() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00Y', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00Y', GetEventDamageSource() )
else
if ( MU_Check_lvl_four() ) then
call SetPlayerAbilityAvailableBJ( true, 'A013', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A013', GetEventDamageSource() )
else
call DoNothing( )
endif
endif
endif
endif
endfunction
function Trig_MU_Actions takes nothing returns nothing
call DestroyTrigger(udg_MU_trig)
set udg_MU_Venum_counter = GetRandomInt(1, 5)
set udg_MU_TG = GetAttackedUnitBJ()
if ( MU_Venum_Check() ) then
if ( MU_Check_lvl_one() ) then
call UnitAddAbilityBJ( 'A00X', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00X', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_two() ) then
call UnitAddAbilityBJ( 'A00U', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00U', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_three() ) then
call UnitAddAbilityBJ( 'A00Y', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00Y', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_four() ) then
call UnitAddAbilityBJ( 'A013', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A013', GetOwningPlayer(udg_Akame_Killer) )
else
call DoNothing( )
endif
endif
endif
endif
set udg_MU_trig = CreateTrigger()
call TriggerRegisterUnitEvent( udg_MU_trig, udg_MU_TG, EVENT_UNIT_DAMAGED )
call TriggerAddCondition( udg_MU_trig, Condition( function MU_Second_Conditions ) )
call TriggerAddAction( udg_MU_trig, function MU_del )
else
call DoNothing( )
endif
endfunction
//===========================================================================
function InitTrig_MU takes nothing returns nothing
set gg_trg_MU = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_MU, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_MU, Condition( function Trig_MU_Conditions ) )
call TriggerAddAction( gg_trg_MU, function Trig_MU_Actions )
endfunction
Суть триггера:
Имеется способность с четырьмя уровнями. На каждом уровне урон способности разный, а шанс срабатывания всегда 25%. При атаке герой, имеющий такую способность имеет шанс (25%) на отравление противника.
Переменная udg_Akame_killer равносильна GetEventDamageSource()
P.S. Возможно кому-то даже пригодится этот код... Сделан полнейшим неумехой в плане jass, так что не судите строго!
Буран (цель область), Огненный дождь (цель область), Гроза (цель область) - примеры способностей с целью областью.
Веерный бросок (не требует цели ), Жар преисподней (не требует цели, переключатель), Стальной вихрь ( не требует цели, блокирует способности заклинателя ), - способности не требующие указания цели.
глобальный массив не нужен. сохраняй группу в хэш-таблицу на хэндл героя, потом загружай ее когда надо. у каждого героя будет своя группа
вот пример, молот бурь съедает юнита а удар грома ставит всех юнитов обратно
Это давно обсуждалось. вопрос удаление события
Создание триггер события — 3 утечки. Стереть переменный триггер, и минус 1. Получается остается 2 утечки.
Вот если удалить юнита (Remove unit), то он стирается из события другого триггера?
Параметры стака ядов с одним и тем же баффом, это нужно чтобы складывались замедлени и\или урон от разных юнитов, или бафф тупо обновлялся.
С одним из параметров яды с разными баффами скатаются независимо, каждый вешает свой бафф. (годная основа для замедляющих способностей)
А игра вылетает из за зацикливания, темболее бафф при удалении и появлении наносит 0.00 ед урона, это так для справки.
Custom, Никак, HeroAbilityList низя править во время игры, делайте несколько героев с разными наборами скиллов на изучение, а потом морфите.
Как правильно морфить можно найти инфу тут.
Перед морфом желательно убирать все предметы из инвентаря.
Maniac_91, область это хэндл а значит утекает
максимального количества областей ограничивается количеством оперативной памяти (до 2 гигов вроде) и максимальным количеством хэндлов (2 в 32 степени)
больше ни чем EnergyFrost:
Максимум что тебя ожидает- лаги, которые ты получишь из-за утечек, работая с этими областями. Так что старайся не наплодить утечек и все будет окей.
как правило работа со статичными областями не вызывает утечек (если их не копировать)
ограничений на декорации тоже нету к слову (если не юзать устаревший редактор)
Мне что-то такое помнится, что там вроде возможен только один погодный эффект на область. Попробуй создать ещё одну область и там уже создавай второй дождь.
ну есть такая возможность
в [[gameClass2]+0x1B4]+0x14 хранится адрес виджета под мышкой. естественно, деревья не в счет, может, только у рабочих они учитываются
RMem(RMem(RMem(gameClass2)+0x1B4)+0x14)==address
а, я думал, ты хочешь узнать тип объекта по его адресу. конвертировать в джасс сложно, не минуту доставать, позже
globals
integer l__Int2Unit
integer pGetHandleIDStackCounter=GameDLL+0x3A8060//26
integer pConvertAddressToHandleId=GameDLL+0x430C80//26
endglobals
function setInt2Unit takes integer i returns nothing
set l__Int2Unit=i
return Prevents JassHelper from inlining this function
endfunction
function ConvertUnitAddressToHandleID takes integer address returns integer
local integer a=CallThisCallWith1Args(pGetHandleIDStackCounter,RMem(GameState))
return CallThisCallWith3Args(pConvertAddressToHandleId,a,address,0)
endfunction
function Typecast4 takes nothing returns nothing
local unit l__Int2Unit
endfunction
# +nosemanticerror
function I2Unit takes integer i returns unit
call setInt2Unit(ConvertUnitAddressToHandleID(i))
return l__Int2Unit
endfunction
не забудь уточнить, что ВСЕ используемые здесь адреса НЕ делены на 4, или умножай их сам, если делились. GameState вроде был разделен в паблике.
спутал, эта фунция прячет хендл, а не рисовку обеспечивает
function IsFlagBitSet takes integer flags, integer bit returns boolean
if bit!=0 then
return flags/bit*0x80000000 != 0
endif
return false
endfunction
function RMem takes integer addr returns integer
if addr<0 or addr>0x7FFFFFFF then
return 0
endif
return Memory[addr/4]
endfunction
function AddAlwaysVisibleFlag takes unit u returns nothing
local integer a=ConvertHandle(u)
if a>0 and IsFlagBitSet(RMem(a+0x20),0x10)==false then
call WMem(a+0x20,RMem(a+0x20)+0x10)
endif
endfunction
вместо юнита можно вроде любой виджет, просто смени входящий тип и проверь
у отряда мало возможности, если бы былобы такое то двигал бы через отряд..
Чего? Нет никакой разницы, что ты каждого юнита занесешь в массив, и будешь перебирать его циклом, что ткнешь Pick every unit in (unit group) and do multiple actions и выполнишь точно такой же цикл.
Я предпочитаю отряд.
Да и таймер нахер, если честно. Коли тебе в любом случае придется работать с событиями с малым периодом, гораздо удобнее закрепить за каждым юнитом вещественную переменную, отвечающую за время движения, и каждые 0.02 отнимать от нее 0.02.
Если не понял, пиши, я скину пример.
Частично не понял, тоесть нужно что бы в кинематике был несуществующий юнит?
Допустим в окне кинематики паладин с каким либо именем что то говорит, но на карте его нет. Если да то это Спецэффекты - Transmission From Unit-Type
А касательно остальной части, если UnitUserData нигде не используется, создаешь массив юнитов и отрядов. Массив юнитов забиваешь своими капитанами. В UnitUserData капитана пихаешь его порядковый номер в массиве. Создаешь группу юнитов для этого капитана.
Добавление через каст способности.
Я бы делал через 2 разные абилки с одной и той же позицией в интерфейсе. Пока нужный тебе юнит не является частью отряда - у него таргетная абилка при касте которой на капитана он добавляется в группу соответствующего капитана и получает 2ю абилку взамен первой.
Касательно выделения этих пехотинцев - можно намутить что-то с передачей контроля или создать триггер, который будет снимать выделение с юнитов у которых есть 2я абилка. Если ты хочешь чтобы по одиночке можно было выделять пехотинцев - можешь создать переменную для каждого игрока с капитанами, куда будет просто записываться последний выбранный юнит. При снятии выделения - проверять не выбран ли этот же юнит, в случае чего не снимать выделение. Правда не уверен будет ли корректно работать :> В крайнем случае - будет работать в три клика вместо двух. Если я не ошибаюсь.
Касательно поведения этих пехотинцев - что-то реально стоящее сделать сложно. Возможно, но мне не с руки все расписывать :> Простейший вариант - приказывать пехотинцам после добавления в группу следовать за капитаном.
Добавление через атаку капитана
Триггер, проверяющий что капитан получил урон или атакован, как угодно. Далее любым способом проверяешь есть ли в группе этого капитана юниты. Если нет - выбираешь всех пехотинцев N радиусе, добавляешь в отряд, заменяешь абилку/либо просто приказываешь кастануть в капитана первую абилку.
filterGetUnitsOfTypeIdAll - фильтр, вместо него должно быть написано либо null или Condition( function XXX) Короче зачем нужен фильтр? Фильтр при выборе всех юнитов сразу отсеивает не нужных, если по условию не подходит, то выкидывает.. Вам сразу достается готовая группа с нужными юнитами
А в качестве переменных используй GetFilterUnit, GetFilterPlayer. На гуи по-другому называют MatchingUnit
где XXX - название функции, эта функция возвращает boolean (то есть истину или ложь)
вбей в поиск названии функции, может найдешь ответ
например выделяем все здания UNIT_TYPE_STRUCTURE, а те, кто не является зданием отсеиваем
function XXX takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
насчет статьи не видел, это придет с пониманием. Главное начать. Сначала тупо конверт, и оптимизация. А дальше можешь сам
что у тебя там не работает скидывай сюда
Второй комп сломан поэтому проверить не могу, почему у меня подозрение, что оно должно работать.... Хотя могу и ошибаться, нормально делал карты года 2 назад.
Alexander69, xgm.guru/p/wc3/optimisations
внимательно прочти то что там написано
особенно про переменные
если коротко то объект не может быть удалён из памяти пока используется (хранится в переменных/хэше/кэше)
создать.
направить на 128 точек наверх(90)
сделать неперманентным
текст удалится через 3 секунды
текст затухнет до 100% прозрачности через 3 секунды
Вот чёрт. не успел приплюснуть к посту.
скрин скинул выше, но там ошибка. И если раскрыть, то обнаруживается еще одна утечка: на гуи Point(0,0), а на jass эта команда называется по-другому Location(0,0), эта функция создает точку
раскрыть
попробуй раскрутить, и использовать эту
native CreateItem takes integer itemid, real x, real y returns item
через CS: call CreateItem( id, GetUnitX(u), GetUnitY(u))
где id - ид-номер типа предмета, u - юнит. Ввести тип предмета, и юнита нужно.
можно еще запомнить как-то, чтобы к предмету как-то обращаться
через CS: set it = CreateItem( id, GetUnitX(u), GetUnitY(u))
где it - переменная предмета. Объявить переменную и обращаться
» WarCraft 3 / Как сделать два типа юнита?
» WarCraft 3 / Real или Int
» WarCraft 3 / Где скачать русификатор
» WarCraft 3 / Структура
» WarCraft 3 / Где скачать русификатор
» WarCraft 3 / Способность: ледяная стрела.
» WarCraft 3 / Невыделяемый юнит
» WarCraft 3 / Есть ли тут утечки?
» WarCraft 3 / Наносящий урон
» WarCraft 3 / Глобальный таймер
» WarCraft 3 / Событие - получает урон
» WarCraft 3 / система отлова урона
» WarCraft 3 / Морф удаляет способность с эффектом героя!
» WarCraft 3 / Погодные эффекты
» WarCraft 3 / Проблема с моделью
» WarCraft 3 / Memory Hack
» WarCraft 3 / Обработка предметов
» WarCraft 3 / Отряд
» WarCraft 3 / Общий вид
» WarCraft 3 / Урон
» WarCraft 3 / Панель приказов
» Администрация XGM / Вакансии
» WarCraft 3 / Не работает триггер выбора
» WarCraft 3 / Утечки